package org.maiyoframework.core.jpa;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.Query;

/**
 * JPA查询辅助类
 * <P>
 * 通过setWhere方法与Condition对象构造条件查询语句，Condition的创建请查看Condition构造方法注释。
 * <P>
 * 通过setOrderBy方法构造排序语句。
 * <P>
 * 通过setUrlParams方法设置分页时，页码超链接上的参数，
 * 分页有参数时必须进行设置，否则翻页之后记录集将丢失查询条件。
 * 
 * @author maiYo
 * 
 */
public class Finder {
	
	/**
	 * 简单构造Finder对象，设置单一查询条件
	 * 
	 * @param condition
	 *            条件语句对象
	 */
	public Finder(Condition condition) {
		super();
		this.setWhere(condition);
	}
	
	/**
	 * JPA查询辅助类
	 * <P>
	 * 通过setWhere方法与Condition对象构造条件查询语句，Condition的创建请查看Condition构造方法注释。
	 * <P>
	 * 通过setOrderBy方法构造排序语句。
	 * <P>
	 * 通过setUrlParams方法设置分页时，页码超链接上的参数，
	 * 分页有参数时必须进行设置，否则翻页之后记录集将丢失查询条件。
	 */
	public Finder() {
		super();
	}

	/**
	 * 创建JPQL带占位符(?1)的WHERE语句部分
	 * 
	 * @return
	 */
	public String createWhere() {
		StringBuilder sb = new StringBuilder();
		List<Condition> wh = this.getWhere();
		if (wh != null && wh.size() > 0) {
			sb.append(" where");
			for (int i = 0; i < wh.size(); i++) {
				sb.append(" bean.").append(wh.get(i).getProperty());
				if (wh.get(i).getParameter() != null) {
					sb.append(" ?").append(i + 1)
							.append(" " + wh.get(i).getConnector());
				} else {
					sb.append(" " + wh.get(i).getConnector());
				}
			}
			sb.delete(sb.length() - 3, sb.length());
		}
		return sb.toString();
	}
	
	/**
	 * 设置占位符实际参数，如为?1设置参数
	 * 
	 * @param query
	 */
	public void setParameters(Query query) {
		List<Condition> wh = this.getWhere();
		if (wh != null && wh.size() > 0) {
			for (int i = 0; i < this.getWhere().size(); i++) {
				Object param = this.getWhere().get(i).getParameter();
				if (param != null) {
					query.setParameter(i + 1, param);
				}
			}
		}
	}

	/**
	 * 创建JPQLOrderBy排序语句部分
	 * 
	 * @return
	 */
	public String createOrderBy() {
		StringBuilder sb = new StringBuilder();
		LinkedHashMap<String, String> ob = this.getOrderBy();
		if (ob != null && ob.size() > 0) {
			sb.append(" order by");
			for (String key : ob.keySet()) {
				sb.append(" bean.").append(key).append(" " + ob.get(key))
						.append(",");
			}
			sb.deleteCharAt(sb.length() - 1);
		}
		return sb.toString();
	}
	
	/**
	 * 封装查询条件
	 * 
	 * @param condition
	 *            条件语句对象
	 */
	public void setWhere(Condition condition) {
		this.where.add(condition);
	}
	
	/**
	 * 封装URL参数
	 * 
	 * @param param
	 *            参数名
	 * @param value
	 *            值
	 */
	public void setUrlParams(String param, String value) {
		this.urlParams.put(param, value);
	}

	/**
	 * 封装排序语句
	 * 
	 * @param property
	 *            属性
	 * @param sort
	 *            排序方式
	 */
	public void setOrderBy(String property, String sort) {
		this.orderBy.put(property, sort);
	}
	
	/** 条件条件 */
	private List<Condition> where = new ArrayList<Condition>();
	/** 排序语句 */
	private LinkedHashMap<String, String> orderBy = new LinkedHashMap<String, String>();
	/** 分页页码上超链接参数 */
	private Map<String, String> urlParams = new HashMap<String, String>();
	
	/**
	 * 获取查询条件
	 * 
	 * @return
	 */
	public List<Condition> getWhere() {
		return where;
	}

	/**
	 * 获取排序语句
	 * 
	 * @return
	 */
	public LinkedHashMap<String, String> getOrderBy() {
		return orderBy;
	}

	/**
	 * 获取分页页码上超链接参数
	 * 
	 * @return
	 */
	public Map<String, String> getUrlParams() {
		return urlParams;
	}

}
